#include "../inc/MusicPlayer.h"
#include <unistd.h>
#include <sys/wait.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstring>
#include <signal.h>

/**
 * @brief MusicPlayer类的构造函数
 *
 * 初始化MusicPlayer对象，并设置播放器路径、播放器进程ID和播放状态。
 *
 * @param playerPath 播放器路径
 */
MusicPlayer::MusicPlayer(const std::string& playerPath) 
    : m_playerPath(playerPath), m_playerPid(-1), m_isPlaying(false) {
}

/**
 * @brief 析构函数
 *
 * 在销毁MusicPlayer对象时调用，停止正在播放的音乐。
 */
MusicPlayer::~MusicPlayer() 
{
    stop();
}

/**
 * @brief 播放音乐文件
 *
 * 使用 mplayer 播放指定路径的音乐文件。
 *
 * @param filePath 音乐文件路径
 * @return 如果播放成功返回 true，否则返回 false
 */
bool MusicPlayer::play(const std::string& filePath) 
{
    // 如果已经在播放，先停止
    if (m_isPlaying) 
    {
        stop();
    }

    // 检查文件是否存在
    std::ifstream file(filePath);
    if (!file.good()) 
    {
        std::cerr << "Error: File " << filePath << " does not exist or cannot be accessed." << std::endl;
        return false;
    }

    pid_t pid = fork();// 创建子进程
    if (pid == 0) 
    {
        // 子进程
        execl(m_playerPath.c_str(), "mplayer", filePath.c_str(), (char*)NULL);
        // 如果execl失败
        std::cerr << "Failed to execute mplayer" << std::endl;
        exit(1);
    } 
    else if (pid > 0) 
    {
        // 父进程
        m_playerPid = pid;
        m_isPlaying = true;
        m_currentFile = filePath;
        return true;
    } 
    else 
    {
        // fork失败
        std::cerr << "Failed to fork process for mplayer" << std::endl;
        return false;
    }
}

/**
 * @brief 停止播放音乐
 *
 * 停止当前正在播放的音乐，释放相关资源。
 */
void MusicPlayer::stop() 
{
    // 如果正在播放且播放进程ID大于0
    if (m_isPlaying && m_playerPid > 0) 
    {
        // 向播放进程发送SIGTERM信号，以终止进程
        kill(m_playerPid, SIGTERM);
        // 等待播放进程终止
        waitpid(m_playerPid, nullptr, 0);
        // 将播放进程ID重置为-1
        m_playerPid = -1;
        // 将播放状态设置为false
        m_isPlaying = false;
        // 清空当前播放文件
        m_currentFile.clear();
    }
}

/**
 * @brief 暂停音乐播放
 *
 * 如果当前音乐正在播放且播放器进程存在，则暂停播放。
 */
void MusicPlayer::pause() 
{
    if (m_isPlaying && m_playerPid > 0) 
    {
        kill(m_playerPid, SIGSTOP);
    }
}

/**
 * @brief 恢复音乐播放
 *
 * 如果当前音乐正在播放且进程ID有效，则向该进程发送SIGCONT信号以恢复其运行。
 */
void MusicPlayer::resume() 
{
    if (m_isPlaying && m_playerPid > 0) 
    {
        kill(m_playerPid, SIGCONT);
    }
}

/**
 * @brief 设置音乐播放器的音量
 *
 * 设置音乐播放器的音量。如果音量小于0，则自动设置为0；如果音量大于100，则自动设置为100。
 * 如果当前正在播放音乐并且播放进程ID大于0，则通过调用`amixer`命令调整音量。
 *
 * @param volume 音量值，范围在0到100之间
 */
void MusicPlayer::setVolume(int volume) 
{
    if (volume < 0) volume = 0;
    if (volume > 100) volume = 100;

    if (m_isPlaying && m_playerPid > 0) 
    {
        std::string cmd = "amixer set PCM " + std::to_string(volume) + "%";
        system(cmd.c_str());
    }
}

/**
 * @brief 判断音乐播放器是否正在播放
 *
 * 判断当前音乐播放器是否正在播放音乐。
 *
 * @return 如果音乐播放器正在播放，则返回true；否则返回false。
 */
bool MusicPlayer::isPlaying() const 
{
    return m_isPlaying;
}

/**
 * @brief 检查音乐播放器是否已结束
 *
 * 判断当前音乐播放器进程是否已结束。
 *
 * @return 如果音乐播放器进程已结束，则返回true；否则返回false。
 */
bool MusicPlayer::isFinished() const 
{
    if (m_playerPid <= 0) return true;
    
    int status;
    pid_t result = waitpid(m_playerPid, &status, WNOHANG);
    if (result == 0) {
        // 进程仍在运行
        return false;
    } else if (result == -1) {
        // 出错或进程已结束
        return true;
    } else {
        // 进程已结束
        return true;
    }
}

/**
 * @brief 执行命令并返回输出结果
 *
 * 该函数通过执行外部命令，并将命令的输出结果存储在一个字符串向量中返回。
 *
 * @param cmd 要执行的命令
 * @return 包含命令输出结果的字符串向量
 */
std::vector<std::string> MusicPlayer::executeCommand(const std::string& cmd) 
{
    std::vector<std::string> output;
    FILE* pipe = popen(cmd.c_str(), "r");
    if (!pipe) 
    {
        return output;
    }

    char buffer[128];
    while (fgets(buffer, sizeof(buffer), pipe) != nullptr) 
    {
        output.push_back(buffer);
    }

    pclose(pipe);
    return output;
}

// int main() {
//     MusicPlayer player;
    
//     // 播放音频文件
//     if (player.play("touch.wav")) 
//     {
//         std::cout << "Playing audio..." << std::endl;
        
//         // 等待5秒
//         sleep(5);
        
//         // 暂停
//         player.pause();
//         std::cout << "Paused playback" << std::endl;
        
//         // 等待2秒
//         sleep(2);
        
//         // 继续播放
//         player.resume();
//         std::cout << "Resumed playback" << std::endl;
        
//         // 等待播放结束或按需停止
//         // player.stop();
//     } else {
//         std::cerr << "Failed to play audio" << std::endl;
//     }

//     return 0;
// }